package repository

import (
	"context"
	"errors"

	"gorm.io/gorm"

	"BookStack/internal/domain/book"
)

// recycleBinRepository 回收站仓储实现
type recycleBinRepository struct {
	db *gorm.DB
}

// NewRecycleBinRepository 创建回收站仓储
func NewRecycleBinRepository(db *gorm.DB) book.RecycleBinRepository {
	return &recycleBinRepository{
		db: db,
	}
}

// Create 创建回收站项目
func (r *recycleBinRepository) Create(ctx context.Context, item *book.RecycleItem) error {
	return r.db.WithContext(ctx).Create(item).Error
}

// GetByID 通过ID获取回收站项目
func (r *recycleBinRepository) GetByID(ctx context.Context, id uint) (*book.RecycleItem, error) {
	var item book.RecycleItem
	if err := r.db.WithContext(ctx).First(&item, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, err
	}
	return &item, nil
}

// GetByItemIDAndType 通过项目ID和类型获取回收站项目
func (r *recycleBinRepository) GetByItemIDAndType(ctx context.Context, itemID uint, itemType string) (*book.RecycleItem, error) {
	var item book.RecycleItem
	if err := r.db.WithContext(ctx).
		Where("item_id = ? AND item_type = ?", itemID, itemType).
		First(&item).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, err
	}
	return &item, nil
}

// Update 更新回收站项目
func (r *recycleBinRepository) Update(ctx context.Context, item *book.RecycleItem) error {
	return r.db.WithContext(ctx).Save(item).Error
}

// Delete 删除回收站项目
func (r *recycleBinRepository) Delete(ctx context.Context, id uint) error {
	return r.db.WithContext(ctx).Delete(&book.RecycleItem{}, id).Error
}

// List 获取回收站项目列表
func (r *recycleBinRepository) List(ctx context.Context, offset, limit int) ([]*book.RecycleItem, int64, error) {
	var items []*book.RecycleItem
	var total int64
	query := r.db.WithContext(ctx).Model(&book.RecycleItem{}).
		Where("restored_at IS NULL")

	// 查询总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	if err := query.Offset(offset).Limit(limit).Order("created_at DESC").Find(&items).Error; err != nil {
		return nil, 0, err
	}

	return items, total, nil
}

// ListByType 按类型获取回收站项目列表
func (r *recycleBinRepository) ListByType(ctx context.Context, itemType string, offset, limit int) ([]*book.RecycleItem, int64, error) {
	var items []*book.RecycleItem
	var total int64
	query := r.db.WithContext(ctx).Model(&book.RecycleItem{}).
		Where("item_type = ? AND restored_at IS NULL", itemType)

	// 查询总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	if err := query.Offset(offset).Limit(limit).Order("created_at DESC").Find(&items).Error; err != nil {
		return nil, 0, err
	}

	return items, total, nil
}

// BatchDelete 批量删除回收站项目
func (r *recycleBinRepository) BatchDelete(ctx context.Context, ids []uint) error {
	return r.db.WithContext(ctx).Where("id IN ?", ids).Delete(&book.RecycleItem{}).Error
}

// DeleteByType 按类型删除回收站项目
func (r *recycleBinRepository) DeleteByType(ctx context.Context, itemType string) error {
	return r.db.WithContext(ctx).Where("item_type = ?", itemType).Delete(&book.RecycleItem{}).Error
}

// Clear 清空回收站
func (r *recycleBinRepository) Clear(ctx context.Context) error {
	return r.db.WithContext(ctx).Where("1=1").Delete(&book.RecycleItem{}).Error
}
